#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <QPixmap>
#include <QLabel>

#include "musicId3v2Info.h"



musicId3v2Info::musicId3v2Info()
{
    flag = 0;
    titleSize = 0;
    title = NULL;
    singleSize = 0;
    singer = NULL;
    specialSize = 0;
    special = NULL;
    coverSize = 0;
    cover = NULL;

}

musicId3v2Info::~musicId3v2Info()
{
    if(title != NULL)
    {
        free(title);
    }
    if(singer != NULL)
    {
        free(singer);
    }
    if(special != NULL)
    {
        free(special);
    }
    if(cover != NULL)
    {
        free(cover);
    }
}

int musicId3v2Info::readInfo(char *url)
{

    FILE *pf = fopen(url, "r");
    if(pf == NULL)
    {
        return -1;
    }

    mp3Id3v2Header *mi = (mp3Id3v2Header*) malloc(sizeof(mp3Id3v2Header));
    //mp3Id3v2Header mi[sizeof(mp3Id3v2Header)];
    //mp3Id3v2Header *mi = (mp3Id3v2Header*)

    fread(mi, sizeof(mp3Id3v2Header), 1, pf);

    //if(mi)
    if(mi->header[0] != 'I' || mi->header[1] != 'D' || mi->header[2] != '3')
    {
        free(mi);
        return 0;
    }
    printf("%s\n", mi->header);

    uint32_t frameTotalSize = (mi->size[0]&0x7F)*0x200000
            +(mi->size[1]&0x7F)*0x4000
            +(mi->size[2]&0x7F)*0x80
            +(mi->size[3]&0x7F);

    printf("%d\n", frameTotalSize);
    free(mi);

    uint32_t usedSize = 0;
    mp3Id3v2FrameHeader mfh;
    uint32_t frameSize = 0;
    char *frameData;
    char fIdtmp[5];

    while(usedSize < frameTotalSize)
    {
        memset(fIdtmp, 0, 5);
        fread(fIdtmp, 4, 1, pf);
        if(!strcmp(fIdtmp, "TIT2")
                || !strcmp(fIdtmp, "TPE1")
                || !strcmp(fIdtmp, "TALB")
                || !strcmp(fIdtmp, "APIC")
                || !strcmp(fIdtmp, "COMM"))
        {
            if(fseek(pf, -4, 1))
            {
                return -1;
            }
        }
        else
        {
            if(fseek(pf, -3, 1))
            {
                return -1;
            }
            usedSize += 1;
            continue;
        }
        fread(&mfh, sizeof(mp3Id3v2FrameHeader), 1, pf);
        usedSize += 10;
        //memcpy(&frameSize, mfh.size, 4);
        /*
        frameSize =  mfh.size[0]*0x100000000
                +mfh.size[1]*0x10000
                +mfh.size[2]*0x100
                +mfh.size[3];
                */
        frameSize = mfh.size[0] * 0x1000000
                + mfh.size[1] * 0x10000
                + mfh.size[2] * 0x100
                + mfh.size[3];
        printf("%s ", mfh.frameId);
        printf("%d\n", frameSize);
        frameData = (char*) malloc(frameSize);
        fread(frameData, frameSize, 1, pf);


        frameOp(&mfh, frameData, frameSize);


        usedSize += frameSize;
        free(frameData);
        }

    return 0;
}


int musicId3v2Info::frameOp(mp3Id3v2FrameHeader *mfh, char *fdata, int fsize)
{
    char tmp[5];
    memset(tmp, 0, 5);
    strcat(tmp, mfh->frameId);
    if(strcmp(tmp, "APIC") == 0)
    {
        FILE *pf = fopen("out.jpg", "w");
        fwrite(fdata + 14, fsize - 14, 1, pf);
        fclose(pf);

        this->flag = this->flag | APIC;
        if(this->cover != NULL)
        {
            free(this->cover);
            this->cover = NULL;
        }
        this->cover = (char *) malloc(fsize - 14);
        //strcpy(fdata + 14);
        memcpy(this->cover, fdata + 14, fsize - 14);
        this->coverSize = fsize - 14;
    }
    else if(!strcmp(tmp, "TPE1"))
    {
        this->flag = this->flag | TPE1;
        if(this->singer != NULL)
        {
            free(this->singer);
            this->singer = NULL;
        }

        this->singer = (char *) malloc(fsize);
        memcpy(this->singer, fdata, fsize);
        this->singleSize = fsize;

    }
    else if(!strcmp(tmp, "TIT2"))
    {
        this->flag = this->flag | TIT2;
        if(this->title != NULL)
        {
            free(this->title);
            this->title = NULL;
        }

        this->title = (char *) malloc(fsize);
        memcpy(this->title, fdata, fsize);
        this->titleSize = fsize;
    }
    else if(!strcmp(tmp, "TALB"))
    {
        this->flag = this->flag | TALB;
        if(this->special != NULL)
        {
            free(this->special);
            this->special = NULL;
        }

        char tmpC[fsize];
        memcpy(tmpC, fdata, fsize);


        this->special = (char *) malloc(fsize);
        memcpy(this->special, fdata, fsize);
        this->specialSize = fsize;


    }
    return 0;
}


void musicId3v2Info::show()
{
    QString qstr;
    if(this->flag & TIT2 == TIT2)
    {
        if(!this->title[0])
        {
            qstr = QString::fromLatin1(this->title + 1);
        }
        else
        {
            QChar *tmpUnicode = (QChar *) malloc(this->titleSize - 1);
            memcpy(tmpUnicode, this->title+1, this->titleSize - 1);
            qstr.setRawData(tmpUnicode, (this->titleSize - 1) / 2);
        }
        printf("%s \n", qstr.toUtf8().data());
    }

    if(this->flag & TPE1 == TPE1)
    {
        if(!this->singer[0])
        {
            qstr = QString::fromLatin1(this->singer + 1);
        }
        else
        {
            QChar *tmpUnicode = (QChar *) malloc(this->singleSize - 1);
            memcpy(tmpUnicode, this->singer+1, this->singleSize - 1);
            qstr.setRawData(tmpUnicode, (this->singleSize - 1) / 2);
        }
        printf("%s \n", qstr.toUtf8().data());
    }

    if(this->flag & TALB == TALB)
    {
        if(!this->special[0])
        {
            qstr = QString::fromLatin1(this->special + 1);
        }
        else
        {
            QChar *tmpUnicode = (QChar *) malloc(this->specialSize - 1);
            memcpy(tmpUnicode, this->special+1, this->specialSize - 1);
            qstr.setRawData(tmpUnicode, (this->specialSize - 1) / 2);
        }
        printf("%s \n", qstr.toUtf8().data());
    }



}
